寫 React 時,新手很容易遇到 useState
異步更新的問題。查找資料時,我發現有人在 reddit 發了一篇文章,表示自己是 React 新手,還因為怕問題太基本或愚蠢而道歉。底下有個很棒的回覆:「這問題雖然基本,但一點都不愚蠢。我敢打賭幾乎每個人都至少犯過一次這個錯誤,所以不用擔心。」這讓我覺得,學習中不要害怕提出問題,重點是透過問題不斷學習和成長。
操作 useState 時發生「慢一步」更新的問題,應該也是初學時容易搞不懂的部分。原因在於當你使用 setState
更新狀態時,React 並不會立即更新,而是將其標記為「需要更新」,並在下一次渲染時才真正更新狀態值。這就是 狀態更新是異步的,因此你在調用 setState
後,如果馬上嘗試獲取新狀態,可能還會得到舊的值。
useState
時,資料更新往往慢一步,這是因為狀態更新是異步進行的:const [count, setCount] = useState(0);
const handleIncrement = () => {
setCount(count + 1);
console.log(count); // 可能會預期這裡會顯示更新後的 count,但實際上是舊的值
};
如果希望能夠即時取得更新後的狀態值,該怎麼處理呢?
解決方式:使用 useEffect 來追蹤狀態變化
const [count, setCount] = useState(0);
useEffect(() => {
console.log(count); // 當 count 改變時,這裡會顯示最新的值
}, [count]);
const handleIncrement = () => {
setCount(count + 1);
};
React 之所以選擇異步更新,是為了提升效能。當多次調用 setState
時,React 會將多次更新合併起來,並且在合適的時機一起更新 DOM,避免頻繁的 DOM 操作,從而提高渲染效能。
// 多次 setState 的範例
function App() {
const [count, setCount] = useState(0);
const incrementTwice = () => {
setCount(prevCount => prevCount + 1);
setCount(prevCount => prevCount + 1); // 確保每次更新都基於最新的狀態值
};
return (
<button onClick={incrementTwice}>增加兩次</button>
);
}